home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TeX 1995 July
/
TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO
/
dviware
/
dvipage
/
findfile.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-11
|
10KB
|
504 lines
/*
* dvipage: DVI Previewer Program for Suns
*
* Neil Hunt (hunt@spar.slb.com)
*
* Copyright (c) 1988 Schlumberger Technologies, Inc 1988.
* Anyone can use this software in any manner they choose,
* including modification and redistribution, provided they make
* no charge for it, and these conditions remain unchanged.
*
* This program is distributed as is, with all faults (if any), and
* without any warranty. No author or distributor accepts responsibility
* to anyone for the consequences of using it, or for whether it serves any
* particular purpose at all, or any other reason.
*
* $Log: findfile.c,v $
* Revision 1.1 88/11/28 18:40:44 hunt
* Initial revision
*
* Based upon `mitdrivers/findfile.c'
* Copyright 1985 Massachusetts Institute of Technology
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/dir.h>
#include <sys/file.h>
#include <sys/param.h> /* For MAXPATHLEN */
#include <suntool/sunview.h>
#include "dvipage.h"
forward bool find_file_in_path();
forward bool find_best_file_in_path();
forward bool scandir();
forward bool scanpdir();
forward int strdiff();
/*
* find_file:
* Seaches for a font file in various places.
* dirpath is a colon separated list of possible pathnames.
* Returns TRUE if a usable file was found.
*/
bool find_font_file(dir_path, fontptr)
char *dir_path;
struct font_entry *fontptr;
{
int min_df, min_dp, min_dm;
if(verbose & DEBUG_FONTS)
fprintf(stderr, "find_font_file(%s .%dgf or .%dpxl)\n",
fontptr->n, fontptr->font_gf_mag, fontptr->font_pxl_mag);
/*
* Search for exact match.
*/
if(find_file_in_path(dir_path, fontptr))
return TRUE;
/*
* Search for nearest match.
*/
min_df = min_dp = min_dm = MAXINT;
if(find_best_file_in_path(dir_path, fontptr,
&min_df, &min_dp, &min_dm))
{
message("Substituted font %s for %s.%d.",
fontptr->name, fontptr->n, fontptr->type == TYPE_PXL ?
fontptr->font_pxl_mag : fontptr->font_gf_mag);
return TRUE;
}
return FALSE;
}
/*
* find_file_in_path:
* Searches path for a font file.
* Returns TRUE if a suitable match has been found.
*/
bool
find_file_in_path(dirpath, fontptr)
char *dirpath;
struct font_entry *fontptr;
{
char *p;
char dir[MAXPATHLEN];
while(*dirpath)
{
/*
* Copy first/next path prefix to dir[].
* Skip over the ':'.
*/
for(p = dir; *dirpath; )
{
if(*dirpath == ':' || *dirpath == ';')
{
dirpath++;
break;
}
else
*p++ = *dirpath++;
}
*p = '\0';
if(use_pk)
{
/*
* Try flat structure.
*/
sprintf(fontptr->name, "%s/%s.%dpk",
dir, fontptr->n, fontptr->font_gf_mag);
if(access(fontptr->name, R_OK) == 0)
{
if(verbose & DEBUG_FONTS)
fprintf(stderr, " Try %s; OK\n",
fontptr->name);
fontptr->type = TYPE_PK;
return TRUE;
}
else
{
if(verbose & DEBUG_FONTS)
fprintf(stderr, " Try %s; No\n",
fontptr->name);
}
/*
* Try hierarchical structure.
*/
sprintf(fontptr->name, "%s/%s/%s.%dpk",
dir, fontptr->n, fontptr->n, fontptr->font_gf_mag);
if(access(fontptr->name, R_OK) == 0)
{
if(verbose & DEBUG_FONTS)
fprintf(stderr, " Try %s; OK\n",
fontptr->name);
fontptr->type = TYPE_PK;
return TRUE;
}
else
{
if(verbose & DEBUG_FONTS)
fprintf(stderr, " Try %s; No\n",
fontptr->name);
}
}
if(use_gf)
{
/*
* Try flat structure.
*/
sprintf(fontptr->name, "%s/%s.%dgf",
dir, fontptr->n, fontptr->font_gf_mag);
if(access(fontptr->name, R_OK) == 0)
{
if(verbose & DEBUG_FONTS)
fprintf(stderr, " Try %s; OK\n",
fontptr->name);
fontptr->type = TYPE_GF;
return TRUE;
}
else
{
if(verbose & DEBUG_FONTS)
fprintf(stderr, " Try %s; No\n",
fontptr->name);
}
/*
* Try hierarchical structure.
*/
sprintf(fontptr->name, "%s/%s/%s.%dgf",
dir, fontptr->n, fontptr->n, fontptr->font_gf_mag);
if(access(fontptr->name, R_OK) == 0)
{
if(verbose & DEBUG_FONTS)
fprintf(stderr, " Try %s; OK\n",
fontptr->name);
fontptr->type = TYPE_GF;
return TRUE;
}
else
{
if(verbose & DEBUG_FONTS)
fprintf(stderr, " Try %s; No\n",
fontptr->name);
}
}
if(use_pxl)
{
/*
* Try flat structure.
*/
sprintf(fontptr->name, "%s/%s.%dpxl",
dir, fontptr->n, fontptr->font_pxl_mag);
if(access(fontptr->name, R_OK) == 0)
{
if(verbose & DEBUG_FONTS)
fprintf(stderr, " Try %s; OK\n",
fontptr->name);
fontptr->type = TYPE_PXL;
return TRUE;
}
else
{
if(verbose & DEBUG_FONTS)
fprintf(stderr, " Try %s; No\n",
fontptr->name);
}
/*
* Try hierarchical structure.
*/
sprintf(fontptr->name, "%s/%s/%s.%dpxl",
dir, fontptr->n, fontptr->n, fontptr->font_pxl_mag);
if(access(fontptr->name, R_OK) == 0)
{
if(verbose & DEBUG_FONTS)
fprintf(stderr, " Try %s; OK\n",
fontptr->name);
fontptr->type = TYPE_PXL;
return TRUE;
}
else
{
if(verbose & DEBUG_FONTS)
fprintf(stderr, " Try %s; No\n",
fontptr->name);
}
}
}
return FALSE;
}
/*
* find_best_file_in_path:
* Finds the best match to the desired font.
* Returns TRUE if a suitable match is found.
*/
bool
find_best_file_in_path(dirpath, fontptr, p_min_df, p_min_dp, p_min_dm)
char *dirpath;
struct font_entry *fontptr;
int *p_min_df, *p_min_dp, *p_min_dm;
{
register char *p;
char dir[MAXPATHLEN];
bool status = FALSE;
if(verbose & DEBUG_FONTS)
fprintf(stderr, "find_best_font_file(%s .%dgf or %dpxl)\n",
fontptr->n, fontptr->font_gf_mag, fontptr->font_pxl_mag);
/*
* Scan over directories in dirpath.
*/
while(*dirpath)
{
/*
* Copy first/next path prefix to dir[].
* Skip over the ':'.
*/
for(p = dir; *dirpath != '\0'; )
{
if(*dirpath == ':' || *dirpath == ';')
{
dirpath++;
break;
}
else
*p++ = *dirpath++;
}
*p = '\0';
/*
* Scan the directory.
*/
if(scanpdir(dir, fontptr, p_min_df, p_min_dp, p_min_dm))
status = TRUE;
/*
* Scan any subdirectories.
*/
if(scandir(dir, fontptr, p_min_df, p_min_dp, p_min_dm))
status = TRUE;
}
return status;
}
/*
* scandir:
* Scan directory looking for plausible names,
* then recurse to subdirectories for plausible point sizes.
* Returns TRUE if found a more plausible candidate than previous best.
*/
bool
scandir(dir, fontptr, p_min_df, p_min_dp, p_min_dm)
char *dir;
struct font_entry *fontptr;
int *p_min_df, *p_min_dp, *p_min_dm;
{
DIR *dirstream;
struct direct *dirrecord;
char pdir[MAXPATHLEN];
bool status = FALSE;
if(verbose & DEBUG_FONTS)
fprintf(stderr, " scandir(%s .%dgf or .%dpxl)\n",
fontptr->n, fontptr->font_gf_mag, fontptr->font_pxl_mag);
if(! (dirstream = opendir(dir)))
return FALSE;
while(dirrecord = readdir(dirstream))
{
if(dirrecord->d_name[0] != '.')
continue;
if(strdiff(fontptr->n, dirrecord->d_name) <= *p_min_df)
{
sprintf(pdir, "%s/%s", dir, dirrecord->d_name);
if(scanpdir(pdir, fontptr,
p_min_df, p_min_dp, p_min_dm))
status = TRUE;
}
}
closedir(dirstream);
return status;
}
/*
* scanpdir:
* Scan directory looking for plausible names and point sizes.
* Returns TRUE if found a more plausible candidate than previous best.
*/
bool
scanpdir(dir, fontptr, p_min_df, p_min_dp, p_min_dm)
char *dir;
struct font_entry *fontptr;
int *p_min_df, *p_min_dp, *p_min_dm;
{
DIR *dirstream;
struct direct *dirrecord;
char qfamily[MAXPATHLEN];
char qtype[MAXPATHLEN];
int qpoint, qmag, df, dp, dm;
bool status = FALSE;
char family[MAXPATHLEN];
int point;
if(verbose & DEBUG_FONTS)
fprintf(stderr, " scanpdir(%s .%dgf or .%dpxl)\n",
fontptr->n, fontptr->font_gf_mag, fontptr->font_pxl_mag);
/*
* Split out family name, point size and magnification.
*/
if(sscanf(fontptr->n, "%[^0123456789.]%d", family, &point) != 2)
{
message("Font name \"%s\" appears garbled.", fontptr->n);
return FALSE;
}
if(! (dirstream = opendir(dir)))
return FALSE;
while(dirrecord = readdir(dirstream))
{
if(sscanf(dirrecord->d_name, "%[^0123456789.]%d.%d%s",
qfamily, &qpoint, &qmag, qtype) != 4)
continue;
/*
* Is this a GF file.
*/
if(use_gf && strcmp(qtype, "gf") == 0)
{
df = strdiff(family, qfamily);
dp = abs(point - qpoint);
dm = abs(fontptr->font_gf_mag - qmag);
if((df < *p_min_df) ||
(df == *p_min_df && dp < *p_min_dp) ||
(df == *p_min_df && dp == *p_min_dp &&
dm < *p_min_dm))
{
*p_min_df = df;
*p_min_dp = dp;
*p_min_dm = dm;
sprintf(fontptr->name, "%s/%s",
dir, dirrecord->d_name);
fontptr->type = TYPE_GF;
if(verbose & DEBUG_FONTS)
fprintf(stderr,
" New best match (%d %d %d) is %s\n",
df, dp, dm, fontptr->name);
status = TRUE;
}
}
/*
* Is this a PXL file.
*/
if(use_pxl && strcmp(qtype, "pxl") == 0)
{
df = strdiff(family, qfamily);
dp = abs(point - qpoint);
dm = abs(fontptr->font_pxl_mag - qmag);
if((df < *p_min_df) ||
(df == *p_min_df && dp < *p_min_dp) ||
(df == *p_min_df && dp == *p_min_dp &&
dm < *p_min_dm))
{
*p_min_df = df;
*p_min_dp = dp;
*p_min_dm = dm;
sprintf(fontptr->name, "%s/%s",
dir, dirrecord->d_name);
fontptr->type = TYPE_PXL;
if(verbose & DEBUG_FONTS)
fprintf(stderr,
" New best match (%d %d %d) is %s\n",
df, dp, dm, fontptr->name);
status = TRUE;
}
}
/*
* Is this a PK file.
*/
if(use_pk && strcmp(qtype, "pk") == 0)
{
df = strdiff(family, qfamily);
dp = abs(point - qpoint);
dm = abs(fontptr->font_gf_mag - qmag);
if((df < *p_min_df) ||
(df == *p_min_df && dp < *p_min_dp) ||
(df == *p_min_df && dp == *p_min_dp &&
dm < *p_min_dm))
{
*p_min_df = df;
*p_min_dp = dp;
*p_min_dm = dm;
sprintf(fontptr->name, "%s/%s",
dir, dirrecord->d_name);
fontptr->type = TYPE_PK;
if(verbose & DEBUG_FONTS)
fprintf(stderr,
" New best match (%d %d %d) is %s\n",
df, dp, dm, fontptr->name);
status = TRUE;
}
}
}
closedir(dirstream);
return status;
}
/*
* strdiff:
* Quantify differences in font names.
*/
int
strdiff(s1, s2)
char *s1, *s2;
{
register int diff = 0;
while(*s1 && *s2)
diff += abs(*s1++ - *s2++);
while(*s1)
diff += *s1++;
while(*s2)
diff += *s2++;
return diff;
}